package instruction

import (
	"gitee.com/microwww/jvm-go/jvm/rtda"
)

type IFEQ struct {
	offsetInstruct
}

func (f *IFEQ) Execute(fm *rtda.MethodFrame) {
	v := fm.OperationStack().PopInt()
	if v == 0 {
		f.Branch(fm)
	}
}

type IFNE struct {
	offsetInstruct
}

func (f *IFNE) Execute(fm *rtda.MethodFrame) {
	v := fm.OperationStack().PopInt()
	if v != 0 {
		f.Branch(fm)
	}
}

type IFLT struct {
	offsetInstruct
}

func (f *IFLT) Execute(fm *rtda.MethodFrame) {
	v := fm.OperationStack().PopInt()
	if v < 0 {
		f.Branch(fm)
	}
}

type IFLE struct {
	offsetInstruct
}

func (f *IFLE) Execute(fm *rtda.MethodFrame) {
	v := fm.OperationStack().PopInt()
	if v <= 0 {
		f.Branch(fm)
	}
}

type IFGT struct {
	offsetInstruct
}

func (f *IFGT) Execute(fm *rtda.MethodFrame) {
	v := fm.OperationStack().PopInt()
	if v > 0 {
		f.Branch(fm)
	}
}

type IFGE struct {
	offsetInstruct
}

func (f *IFGE) Execute(fm *rtda.MethodFrame) {
	v := fm.OperationStack().PopInt()
	if v >= 0 {
		f.Branch(fm)
	}
}

type IFICMPEQ struct {
	offsetInstruct
}

func (f *IFICMPEQ) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopInt()
	val := fm.OperationStack().PopInt()
	if val == cmp {
		f.Branch(fm)
	}
}

type IFICMPNE struct {
	offsetInstruct
}

func (f *IFICMPNE) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopInt()
	val := fm.OperationStack().PopInt()
	if val != cmp {
		f.Branch(fm)
	}
}

type IFICMPLT struct {
	offsetInstruct
}

func (f *IFICMPLT) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopInt()
	val := fm.OperationStack().PopInt()
	if val < cmp {
		f.Branch(fm)
	}
}

type IFICMPLE struct {
	offsetInstruct
}

func (f *IFICMPLE) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopInt()
	val := fm.OperationStack().PopInt()
	if val <= cmp {
		f.Branch(fm)
	}
}

type IFICMPGT struct {
	offsetInstruct
}

func (f *IFICMPGT) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopInt()
	val := fm.OperationStack().PopInt()
	if val > cmp {
		f.Branch(fm)
	}
}

type IFICMPGE struct {
	offsetInstruct
}

func (f *IFICMPGE) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopInt()
	val := fm.OperationStack().PopInt()
	if val >= cmp {
		f.Branch(fm)
	}
}

type IFACMPEQ struct {
	offsetInstruct
}

func (f *IFACMPEQ) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopRef()
	val := fm.OperationStack().PopRef()
	if val == cmp {
		f.Branch(fm)
	}
}

type IFACMPNE struct {
	offsetInstruct
}

func (f *IFACMPNE) Execute(fm *rtda.MethodFrame) {
	cmp := fm.OperationStack().PopRef()
	val := fm.OperationStack().PopRef()
	if val != cmp {
		f.Branch(fm)
	}
}

type IFNULL struct {
	offsetInstruct
}

func (f *IFNULL) Execute(fm *rtda.MethodFrame) {
	val := fm.OperationStack().PopRef()
	if val == nil {
		f.Branch(fm)
	}
}

type IFNONNULL struct {
	offsetInstruct
}

func (f *IFNONNULL) Execute(fm *rtda.MethodFrame) {
	val := fm.OperationStack().PopRef()
	if val != nil {
		f.Branch(fm)
	}
}
